home *** CD-ROM | disk | FTP | other *** search
- #ifndef MSC
-
- /* Non-MSC Version */
-
- #if (defined(M_I86CM) || defined(M_I86LM) || defined(M_I86HM))
-
- /* NOTE: These procedures should only be used for
- large data model programs (i.e., Compact, Large, Huge) */
-
- #include <stddef.h>
- #include <stdlib.h>
- #include <dos.h>
- #include "alloc.h"
-
- extern ATABLE AllocationTable [] ; /* Provide storage for block pointers */
- extern SUNIT TABLESIZE ; /* Maximum allocation table size */
- extern SUNIT MBSize ; /* Default allocation block size */
- extern SUNIT NEntry ; /* Number of table entries */
-
- SUNIT *FindBlock ( Header, Size )
-
- HEADER *Header ;
- SUNIT Size ;
-
- /*
- +---------------------------------------+
- | |
- | This procedure searches the given |
- | block (pointed to by Header) for |
- | a block large enough to hold 'Size' |
- | bytes. If one is found, the block |
- | is set to 'in use' and it's address |
- | is returned. |
- | |
- +---------------------------------------+
- */
-
- {
- SUNIT *bptr ;
- SUNIT offset ;
- SUNIT bsize ;
-
-
- if ( Header->HeaderSize != HSIZE )
- return ( NULL ) ;
-
- /* Check if largest free block is large enough for allocation */
-
- if ( Header->Collapsed && Header->LFBlock < Size )
- return ( NULL ) ;
-
- /* Yes. So search block for free location */
-
- offset = HSIZE ;
- while ( offset < Header->BytesUsed ) {
- bptr = (SUNIT *) Header + offset/SSIZE ;
- bsize = *bptr & ~FREE ;
- if ( (*bptr & FREE) && bsize >= Size ) {
- *bptr = bsize ;
- if ( bsize > Size ) {
- offset += Size+SSIZE ;
- *((SUNIT *)Header+offset/SSIZE) = (bsize - Size - SSIZE) | FREE ;
- *bptr = Size ;
- Header->Collapsed = FALSE ;
- } ;
- return ( (bptr+1) ) ;
- } ;
- offset += bsize+SSIZE ;
- } ;
- return ( NULL ) ;
- }
-
- int ExpandBlock ( Header, Size )
-
- HEADER *Header ;
- SUNIT Size ;
-
- /*
- +---------------------------------------+
- | |
- | This procedure attempts to expand |
- | the given block by large enough |
- | to hold an allocation of size 'Size'.|
- | If successful, a value of TRUE is |
- | returned. |
- | |
- +---------------------------------------+
- */
-
- {
- SUNIT *bptr ;
- SUNIT offset ;
- SUNIT bsize ;
- SUNIT nu ;
- SUNIT IncreaseBlockSize () ;
-
- if ( Header->HeaderSize != HSIZE )
- return ( FALSE ) ;
-
- /* Find last block in allocation */
-
- offset = HSIZE ;
- while ( offset < Header->BytesUsed ) {
- bptr = (SUNIT *) Header + offset/SSIZE ;
- bsize = *bptr & ~FREE ;
- offset += bsize+SSIZE ;
- } ;
-
- /* If free, adjust Size appropriately to not have excessive
- memory allocation. */
-
- if ( *bptr & FREE )
- Size -= bsize ;
-
- nu = MBSize * (( Size + SSIZE - 1 ) / MBSize + 1 ) ;
- if ((long) Header->BytesUsed + (long) nu > (long) MAXBLOCK ) {
- nu = NALLOC * ((MAXBLOCK - Header->BytesUsed)/NALLOC ) ;
- if ( nu < Size )
- return ( FALSE ) ;
- } ;
-
- nu = IncreaseBlockSize ( Header, nu ) ;
- if ( nu < Size )
- return ( FALSE ) ;
- if ( *bptr & FREE ) {
- *bptr += nu ;
- if ( Header->Collapsed )
- Header->LFBlock = max ( Header->LFBlock, (bsize+nu)) ;
- }
- else if ( nu > 0 ) {
- bptr = (SUNIT *) Header + offset/SSIZE ;
- *bptr = (nu - SSIZE) | FREE ;
- if ( Header->Collapsed )
- Header->LFBlock = max ( Header->LFBlock, (nu-SSIZE)) ;
- } ;
- return ( TRUE ) ;
- }
-
- HEADER *CheckBlock ( ap, offset )
-
- void *ap ; /* Pointer to allocation block */
- SUNIT *offset ; /* Offset of ap - SSIZE (returned) */
-
- /*
- +---------------------------------------+
- | |
- | This procedure checks the block |
- | given to insure that it is a valid |
- | allocated block. |
- | |
- +---------------------------------------+
- */
-
- {
- HEADER *Header ;
- int i ;
- int ok ;
-
- FP_SEG (Header) = FP_SEG (ap) ;
- FP_OFF (Header) = 0 ;
- ok = FALSE ;
- *offset = 0 ;
- for ( i = 0 ; i < NEntry ; i++ )
- if ( Header == AllocationTable [i].Header &&
- Header->BytesUsed == AllocationTable [i].Size ) {
- ok = TRUE ;
- break ;
- } ;
- if ( ! ok || Header->HeaderSize != HSIZE )
- return ( NULL ) ;
-
- *offset = FP_OFF (ap) - SSIZE ;
- if ( *offset < HSIZE || *offset > Header->BytesUsed )
- return ( NULL ) ;
-
- return ( Header ) ;
- }
-
- void CollapseFreeBlocks ( Header )
-
- HEADER *Header ;
-
- /*
- +---------------------------------------+
- | |
- | This procedure checks the block |
- | given for free allocations and |
- | collapses adjacent free blocks into |
- | single free blocks. |
- | |
- +---------------------------------------+
- */
-
- {
- SUNIT offset ;
- SUNIT bsize ;
- SUNIT nsize ;
- SUNIT maxb ;
- SUNIT *bptr ;
-
- /* If block has already been collapsed, return */
-
- if ( Header->Collapsed )
- return ;
-
- /* Collapse ajacent free blocks into single blocks */
-
- offset = HSIZE ;
- maxb = 0 ;
- while ( offset < Header->BytesUsed ) {
- bptr = (SUNIT *) Header + offset/SSIZE ;
- bsize = *bptr & ~FREE ;
- if ( *bptr & FREE ) {
- maxb = max ( bsize, maxb ) ;
- if ((offset+bsize+SSIZE) < Header->BytesUsed ) {
- if ((nsize = *(bptr+bsize/SSIZE+1)) & FREE )
- *bptr += (nsize & ~FREE) + SSIZE ;
- else
- offset += bsize + SSIZE ;
- }
- else
- break ;
- }
- else
- offset += bsize + SSIZE ;
- } ;
- Header->Collapsed = TRUE ;
- Header->LFBlock = maxb ;
- }
-
- void FreeEmptyBlocks ( Header )
-
- HEADER *Header ;
-
- /*
- +---------------------------------------+
- | |
- | This procedure proceeds backward |
- | from the highest allocated block |
- | and frees any totally empty ones |
- | back to the system. It stops when |
- | it encounters a non-empty block. |
- | |
- +---------------------------------------+
- */
-
- {
- SUNIT *bptr ;
-
- if ( NEntry > 0 && Header == AllocationTable [NEntry-1]. Header ) {
- bptr = (SUNIT *) Header + HSIZE/SSIZE ;
- while ( (*bptr & FREE) &&
- (*bptr & ~FREE) == (Header->BytesUsed-HSIZE-SSIZE) ) {
- FreeBlock ( Header ) ;
- AllocationTable [--NEntry].Header = NULL ;
- AllocationTable [ NEntry].Size = 0 ;
- if ( NEntry == 0 )
- break ;
- Header = AllocationTable [NEntry-1].Header ;
- bptr = (SUNIT *) Header + HSIZE/SSIZE ;
- } ;
- } ;
- }
-
- void NormalizeMBSize ()
-
- /*
- +---------------------------------------+
- | |
- | This procedure normalizes the |
- | block allocation size variable just |
- | in case the user has set it to |
- | something wierd. |
- | |
- +---------------------------------------+
- */
-
- {
-
- if ( MBSize > MAXALLOC )
- MBSize = MAXALLOC ;
- else if ( MBSize < MINALLOC )
- MBSize = MINALLOC ;
- MBSize = NALLOC * ( ( MBSize - 1 ) / NALLOC + 1 ) ;
- }
-
- HEADER *AllocateBlock ( Size )
-
- SUNIT Size ; /* Number of bytes to allocate */
-
- /*
- +---------------------------------------+
- | |
- | Ask system for another block |
- | |
- +---------------------------------------+
- */
-
- {
- HEADER *Header ;
- size_t segment ;
-
-
- /* Allocate a new block */
-
- if ( _dos_allocmem ( (unsigned) Size / NALLOC, &segment ) != 0 )
- return ( NULL ) ;
-
- FP_SEG (Header) = segment ;
- FP_OFF (Header) = 0 ;
- Header->HeaderSize = HSIZE ;
- Header->BytesUsed = Size ;
- Header->Collapsed = TRUE ;
- Header->LFBlock = Size - HSIZE - SSIZE ;
- *((SUNIT *) Header + HSIZE/SSIZE) = Header->LFBlock | FREE ;
-
- return ( Header ) ;
- }
-
- static SUNIT IncreaseBlockSize ( Header, Size )
-
- HEADER *Header ; /* Pointer to header of block */
- SUNIT Size ; /* Number of bytes to expand block by */
-
- /*
- +---------------------------------------+
- | |
- | Ask system to expand given block. |
- | Returns number of bytes block was |
- | expanded by. |
- | |
- +---------------------------------------+
- */
-
- {
- size_t maxsize ;
-
- if ( _dos_setblock ( (Header->BytesUsed + Size)/NALLOC, FP_SEG (Header),
- &maxsize ) != 0 )
- Size = 0 ;
- else
- Header->BytesUsed += Size ;
- return ( Size ) ;
- }
-
- static int FreeBlock ( Header )
-
- HEADER *Header ; /* Pointer to header of block */
-
- /*
- +---------------------------------------+
- | |
- | Free memory block to system. |
- | |
- +---------------------------------------+
- */
-
- {
- if ( _dos_freemem ( FP_SEG (Header) ) != 0 )
- return ( FALSE ) ;
- return ( TRUE ) ;
- }
-
- #endif
- #endif
-
-